package mpc;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.ArrayList;

import javax.swing.JLabel;

public class Tree_Node {
	
	private static ArrayList<Integer> quantInRows, widthInRow;
	
	protected Tree_Node left, right, parent;
	private int level, placeInRow, widthBefore, labelWidth;
	private double centerPositionForNiceMode;
	private static double minNormalPos = 100, maxNormalPos = 0;
	private static int maxLevel, maxPixelWidthForEffectiveMode, maxPixelWidthForNiceMode, labelHeight;
	private static FontMetrics mtr;
	
	protected String label;
	//private final int value;
	
	protected Color color;
	
	public Tree_Node(String label, Color color) {
		this.label = label;
		this.color = color;
		//value = 0;
	}
	
	protected Tree_Node(){
		
	}
	
	/*
	public Tree_Node(int value){
		this.label = value + "";
		this.value = value;
		this.color = Color.black;
	}
	
	*/
	
	public void checkTree(){
		System.out.println("Label: " + label + " level: " + level
				+ " MaxLevel: " + maxLevel + " PlaceInRow: " + placeInRow + " RowLength: " + rowLength());
		if(left != null)
			left.checkTree();
		if(right != null)
			right.checkTree();
	}
	
	private void completeList(int currDeep, int divizor, double normalizedPosition){
		
		if(minNormalPos > normalizedPosition)
			minNormalPos = normalizedPosition;
		if(maxNormalPos < normalizedPosition)
			maxNormalPos = normalizedPosition;
		
		
		if(quantInRows.size() <= currDeep){
			quantInRows.add(0);
			widthInRow.add(0);
		}
		
		if(maxLevel < currDeep)
			maxLevel = currDeep;
		
		this.level = currDeep;
		
		centerPositionForNiceMode = normalizedPosition;
		
		this.placeInRow = quantInRows.get(currDeep);
		quantInRows.set(currDeep, quantInRows.get(currDeep) + 1);
		this.widthBefore = widthInRow.get(currDeep);
		widthInRow.set(currDeep, widthInRow.get(currDeep) + mtr.stringWidth(label));
		
		labelWidth = mtr.stringWidth(label);
		//labelHeight = mtr.getHeight();
		
		if(maxPixelWidthForEffectiveMode < widthInRow.get(currDeep) + placeInRow * 40)
			maxPixelWidthForEffectiveMode = widthInRow.get(currDeep) + placeInRow * 40;
		/*
		if(maxPixelWidthForNiceMode < labelWidth * divizor / 2 + 40)
			maxPixelWidthForNiceMode = labelWidth * divizor / 2 + 40;
		*/
		if(maxPixelWidthForNiceMode < 30 * divizor / 2 + 40)
			maxPixelWidthForNiceMode = 30 * divizor / 2 + 40;
		
		if(left != null){
			left.completeList(currDeep + 1, divizor * 2, normalizedPosition - 1.0 / (divizor * 2));
		}
		
		if(right != null){
			right.completeList(currDeep + 1, divizor * 2, normalizedPosition + 1.0 / (divizor * 2));
		}
	}
	
	public void initSituation(FontMetrics mtr){
		
		Tree_Node.mtr = mtr;
		
		quantInRows = new ArrayList<Integer>();
		widthInRow = new ArrayList<Integer>();
		maxPixelWidthForEffectiveMode = 0;
		maxPixelWidthForNiceMode = 0;
		minNormalPos = 100;
		maxNormalPos = 0;
		
		labelHeight = mtr.getHeight();
		maxLevel = 0;
		completeList(0, 2, 0.5);
		maxLevel++;
	}
	
	public void addLeftSone(Tree_Node left){
		if ((this.left != null) || (left == null)) return;
		left.parent = this;
		this.left = left;
	}
	
	public void addRightSone(Tree_Node right){
		if ((this.right != null) || (right == null)) return;
		right.parent = this;
		this.right = right;
	}
	
	public int level(){return level;}
	public int numberOfLevels(){return maxLevel;}
	public int placeInRow(){return placeInRow;}
	public int widthBefore(){return widthBefore;}
	public int rowLength(){return quantInRows.get(level);}
	public int fullWidthInRow(){return widthInRow.get(level);}
	public int labelWidth(){return labelWidth;}
	public int labelHeight(){return labelHeight;}
	public int minTreePixelWidthForEffectiveMode(){return maxPixelWidthForEffectiveMode;}
	public int minTreePixelWidthForNiceMode(){return (int) Math.round(maxPixelWidthForNiceMode * (1 - minNormalPos) / 
			(maxNormalPos - minNormalPos));}
	public int minTreePixelHeight(){return maxLevel * (labelHeight + 30);}
	public double minNormalPos(){return minNormalPos;}
	public double maxNormalPos(){return maxNormalPos;}
	
	//public int getValue(){return value;}
	
	public double centerPositionForNiceMode(){return maxNormalPos == minNormalPos ?
			0.5 : (centerPositionForNiceMode - minNormalPos) / (maxNormalPos - minNormalPos);}
	
	public Tree_Node leftSone(){return left;}
	public Tree_Node rightSone(){return right;}
	public Tree_Node getParent(){return parent;}
	
	public Color getColor(){return color;}
	public String getLabel(){return label;}
	
	/*
	public JLabel getJLabel(){
		JLabel r = new JLabel(label, JLabel.CENTER);
		return r;
	}
	*/
}
